import plugin from '../../lib/plugins/plugin.js';
import { Restart } from '../other/restart.js';
import { promises as fs } from 'fs';
import { exec } from 'child_process';
import { promisify } from 'util';
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';

const execAsync = promisify(exec);

export class FengyunUpdate extends plugin {
  constructor() {
    super({
      name: '风云插件更新',
      dsc: '风云插件的更新管理',
      event: 'message',
      priority: 5000,
      rule: [
        {
          reg: '^#风云(插件)?更新$',
          fnc: 'handleUpdate',
          permission: 'master'
        },
        {
          reg: '^#风云(插件)?强制更新$',
          fnc: 'handleForceUpdate',
          permission: 'master'
        },
        {
          reg: '^#风云更新状态$',
          fnc: 'handleStatus',
          permission: 'master'
        }
      ]
    });

    // 动态获取当前文件所在目录
    const __filename = fileURLToPath(import.meta.url);
    const __dirname = dirname(__filename);

    // 配置信息
    this.config = {
      repoUrl: 'https://gitee.com/fengyunnb/fengyun-plugin.git',
      branch: 'main',
      pluginDir: this.detectPluginDir(__dirname)
    };

    this.logPrefix = '';
    console.log(`${this.logPrefix}  1 ${this.config.pluginDir}`);
  }

  /**
   * 动态检测插件目录
   */
  detectPluginDir(currentDir) {
    try {
      let dir = currentDir;
      
      // 向上查找直到找到plugins目录
      while (dir && !dir.endsWith('plugins')) {
        const parentDir = dirname(dir);
        if (parentDir === dir) break;
        dir = parentDir;
      }
      
      if (dir.endsWith('plugins')) {
        // 检查可能的目录名称
        const possibleDirs = [
          join(dir, 'fengyun-plugin'),
          join(dir, 'fengyun-plugins'),
          join(dir, 'fengyubn'),
          join(dir, 'fengyun')
        ];
        
        for (const possibleDir of possibleDirs) {
          try {
            const fs = require('fs');
            if (fs.existsSync(possibleDir)) {
              console.log(`${this.logPrefix} 找到插件目录: ${possibleDir}`);
              return possibleDir;
            }
          } catch (e) {
            // 忽略错误
          }
        }
        
        // 默认目录
        return join(dir, 'fengyun-plugin');
      }
      
      return join(process.cwd(), 'plugins', 'fengyun-plugin');
      
    } catch (error) {
      console.error(`${this.logPrefix} 检测插件目录失败:`, error);
      return './plugins/fengyun-plugin';
    }
  }

  /**
   * 处理普通更新
   */
  async handleUpdate(e) {
    try {
      await e.reply('🔄 正在检查风云插件更新...');

      const result = await this.executeUpdate(false);
      
      if (!result.success) {
        // 提供更详细的错误信息
        let errorMsg = `❌ 更新失败：${result.error}`;
        if (result.error.includes('no tracking information')) {
          errorMsg += '\n💡 提示：尝试使用 #风云强制更新 来重置仓库';
        }
        await e.reply(errorMsg);
        return false;
      }

      if (result.hasUpdate) {
        await e.reply(`✅ 风云插件更新成功！\n${result.message}`);
        await this.restartBot(e);
      } else {
        await e.reply('✅ 风云插件已是最新版本');
      }

      return true;

    } catch (error) {
      await e.reply(`❌ 更新异常：${error.message}`);
      return false;
    }
  }

  /**
   * 处理强制更新
   */
  async handleForceUpdate(e) {
    try {
      await e.reply('🚨 开始强制更新风云插件...\n⚠️ 将丢弃所有本地修改！');

      const result = await this.executeUpdate(true);
      
      if (!result.success) {
        await e.reply(`❌ 强制更新失败：${result.error}`);
        return false;
      }

      await e.reply(`✅ 风云插件强制更新成功！\n${result.message}`);
      await this.restartBot(e);

      return true;

    } catch (error) {
      await e.reply(`❌ 强制更新异常：${error.message}`);
      return false;
    }
  }

  /**
   * 处理状态检查
   */
  async handleStatus(e) {
    try {
      await e.reply('📊 正在检查风云插件状态...');

      const status = await this.getGitStatus();
      await e.reply(status);

      return true;
    } catch (error) {
      await e.reply(`❌ 状态检查失败：${error.message}`);
      return false;
    }
  }

  /**
   * 执行更新操作
   */
  async executeUpdate(isForce = false) {
    try {
      // 检查插件目录是否存在
      try {
        await fs.access(this.config.pluginDir);
        console.log(`${this.logPrefix} 插件目录存在: ${this.config.pluginDir}`);
      } catch {
        console.log(`${this.logPrefix} 插件目录不存在，开始克隆仓库...`);
        return await this.cloneRepository();
      }

      // 检查是否是Git仓库
      const isGitRepo = await this.isGitRepository();
      if (!isGitRepo) {
        console.log(`${this.logPrefix} 不是Git仓库，重新初始化...`);
        await this.initGitRepository();
      }

      // 保存当前提交信息
      const currentCommit = await this.getCurrentCommit();
      let updateResult;

      if (isForce) {
        updateResult = await this.forceUpdate();
      } else {
        updateResult = await this.normalUpdate();
      }

      if (!updateResult.success) {
        return updateResult;
      }

      // 检查是否有更新
      const newCommit = await this.getCurrentCommit();
      const hasUpdate = currentCommit !== newCommit;

      let message = '';
      if (hasUpdate) {
        message = `📦 已更新到最新版本\n`;
        message += `🔗 提交: ${newCommit?.substring(0, 8) || '未知'}`;
        
        // 获取更新日志
        if (currentCommit) {
          const log = await this.getUpdateLog(currentCommit, newCommit);
          if (log) {
            message += `\n📝 更新内容:\n${log}`;
          }
        }
      } else {
        message = '📦 已是最新版本';
      }

      if (isForce) {
        message += '\n💥 强制更新：已丢弃所有本地修改';
      }

      return {
        success: true,
        hasUpdate,
        message
      };

    } catch (error) {
      console.error(`${this.logPrefix} 更新执行异常:`, error);
      return {
        success: false,
        error: error.message,
        hasUpdate: false
      };
    }
  }

  /**
   * 普通更新
   */
  async normalUpdate() {
    try {
      // 先检查远程更新
      await execAsync('git fetch origin', { cwd: this.config.pluginDir });
      
      // 尝试拉取更新
      try {
        await execAsync('git pull', { cwd: this.config.pluginDir });
        return { success: true };
      } catch (pullError) {
        console.log(`${this.logPrefix} 普通拉取失败，尝试处理冲突:`, pullError.message);
        
        // 如果有本地修改，先stash
        const hasChanges = await this.hasLocalChanges();
        if (hasChanges) {
          await execAsync('git stash', { cwd: this.config.pluginDir });
          await execAsync('git pull', { cwd: this.config.pluginDir });
          await execAsync('git stash pop', { cwd: this.config.pluginDir });
        } else {
          // 如果没有本地修改，可能是分支问题
          await this.setUpstreamBranch();
          await execAsync('git pull', { cwd: this.config.pluginDir });
        }
        
        return { success: true };
      }
    } catch (error) {
      return { success: false, error: error.message };
    }
  }

  /**
   * 强制更新
   */
  async forceUpdate() {
    try {
      await execAsync('git fetch origin', { cwd: this.config.pluginDir });
      await execAsync(`git reset --hard origin/${this.config.branch}`, { 
        cwd: this.config.pluginDir 
      });
      await execAsync('git clean -fd', { cwd: this.config.pluginDir });
      return { success: true };
    } catch (error) {
      return { success: false, error: error.message };
    }
  }

  /**
   * 设置上游分支
   */
  async setUpstreamBranch() {
    try {
      await execAsync(`git branch --set-upstream-to=origin/${this.config.branch} ${this.config.branch}`, {
        cwd: this.config.pluginDir
      });
      console.log(`${this.logPrefix} 已设置上游分支`);
    } catch (error) {
      console.error(`${this.logPrefix} 设置上游分支失败:`, error);
      throw error;
    }
  }

  /**
   * 检查是否有本地修改
   */
  async hasLocalChanges() {
    try {
      const { stdout } = await execAsync('git status --porcelain', {
        cwd: this.config.pluginDir
      });
      return stdout.trim().length > 0;
    } catch {
      return false;
    }
  }

  /**
   * 克隆仓库
   */
  async cloneRepository() {
    try {
      // 确保父目录存在
      const parentDir = dirname(this.config.pluginDir);
      await fs.mkdir(parentDir, { recursive: true });
      
      // 克隆仓库
      await execAsync(`git clone -b ${this.config.branch} ${this.config.repoUrl} "${this.config.pluginDir}"`);
      
      console.log(`${this.logPrefix} 仓库克隆成功`);
      return {
        success: true,
        hasUpdate: true,
        message: '🎉 首次安装风云插件成功！'
      };
      
    } catch (error) {
      console.error(`${this.logPrefix} 仓库克隆失败:`, error);
      return { 
        success: false, 
        error: `克隆仓库失败: ${error.message}`,
        hasUpdate: false 
      };
    }
  }

  /**
   * 初始化Git仓库
   */
  async initGitRepository() {
    try {
      await execAsync('git init', { cwd: this.config.pluginDir });
      await execAsync(`git remote add origin ${this.config.repoUrl}`, { 
        cwd: this.config.pluginDir 
      });
      await execAsync('git fetch origin', { cwd: this.config.pluginDir });
      await execAsync(`git checkout -b ${this.config.branch} --track origin/${this.config.branch}`, { 
        cwd: this.config.pluginDir 
      });
      console.log(`${this.logPrefix} Git仓库初始化成功`);
    } catch (error) {
      console.error(`${this.logPrefix} Git仓库初始化失败:`, error);
      throw error;
    }
  }

  /**
   * 检查是否是Git仓库
   */
  async isGitRepository() {
    try {
      await fs.access(join(this.config.pluginDir, '.git'));
      return true;
    } catch {
      return false;
    }
  }

  /**
   * 获取当前提交ID
   */
  async getCurrentCommit() {
    try {
      const { stdout } = await execAsync('git rev-parse HEAD', { 
        cwd: this.config.pluginDir 
      });
      return stdout.trim();
    } catch {
      return null;
    }
  }

  /**
   * 获取更新日志
   */
  async getUpdateLog(oldCommit, newCommit) {
    try {
      const { stdout } = await execAsync(
        `git log ${oldCommit}..${newCommit} --oneline --no-merges`, 
        { cwd: this.config.pluginDir }
      );

      const logs = stdout.split('\n')
        .filter(line => line.trim())
        .slice(0, 10) // 限制最多10条
        .map(line => `• ${line.substring(line.indexOf(' ') + 1)}`)
        .join('\n');

      return logs || '暂无详细更新日志';
    } catch {
      return '暂无详细更新日志';
    }
  }

  /**
   * 获取Git状态
   */
  async getGitStatus() {
    try {
      const [branchResult, commitResult, statusResult, logResult] = await Promise.all([
        this.getCurrentBranch(),
        this.getCurrentCommit(),
        this.getGitStatusInfo(),
        this.getRecentCommits()
      ]);

      let status = '📊 风云插件状态信息\n';
      status += `🌿 当前分支: ${branchResult || '未知'}\n`;
      status += `🔗 最新提交: ${commitResult ? commitResult.substring(0, 8) : '未知'}\n`;
      status += `📁 插件目录: ${this.config.pluginDir}\n\n`;

      if (statusResult) {
        status += `📝 仓库状态:\n${statusResult}\n\n`;
      }

      if (logResult) {
        status += `📋 最近更新:\n${logResult}`;
      }

      return status;

    } catch (error) {
      return `❌ 获取状态失败: ${error.message}`;
    }
  }

  /**
   * 获取当前分支
   */
  async getCurrentBranch() {
    try {
      const { stdout } = await execAsync('git branch --show-current', {
        cwd: this.config.pluginDir
      });
      return stdout.trim();
    } catch {
      return null;
    }
  }

  /**
   * 获取Git状态信息
   */
  async getGitStatusInfo() {
    try {
      const { stdout } = await execAsync('git status --porcelain -b', {
        cwd: this.config.pluginDir
      });
      
      const lines = stdout.split('\n').filter(line => line.trim());
      const status = [];
      
      lines.forEach(line => {
        if (line.startsWith('##')) {
          status.push(`分支信息: ${line.substring(2)}`);
        } else {
          const statusType = line.substring(0, 2);
          const file = line.substring(3);
          status.push(`[${statusType}] ${file}`);
        }
      });
      
      return status.join('\n') || '工作区干净，无修改';
    } catch {
      return '无法获取状态信息';
    }
  }

  /**
   * 获取最近提交
   */
  async getRecentCommits() {
    try {
      const { stdout } = await execAsync('git log --oneline -5', {
        cwd: this.config.pluginDir
      });
      
      return stdout.split('\n')
        .filter(line => line.trim())
        .map(line => `• ${line}`)
        .join('\n');
    } catch {
      return '无法获取提交历史';
    }
  }

  /**
   * 重启机器人
   */
  async restartBot(e) {
    try {
      await e.reply('🔄 更新完成，正在重启机器人...');
      
      // 延迟3秒后重启，让消息发送完成
      setTimeout(() => {
        try {
          new Restart(e).restart();
        } catch (error) {
          console.error(`${this.logPrefix} 重启失败:`, error);
          e.reply('⚠️ 自动重启失败，请手动重启机器人');
        }
      }, 3000);
      
    } catch (error) {
      await e.reply(`⚠️ 重启失败：${error.message}\n💡 请手动重启机器人`);
    }
  }
}